home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PCMania 81
/
PCMania CD81_1.iso
/
PCMANIA
/
demosc81
/
raytrac2.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-05-22
|
7KB
|
234 lines
/*
HEY! PcManíacos:
Si queréis contactar con el autor de esta sección,
ahora podéis hacerlo a través de su e-mail privado:
Miquel Barceló: (Demoscene)
e-mail: MBarceloJ@nexo.es
--------------------------------------------------------------
*/
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <dos.h>
#include <conio.h>
#include <i86.h>
#include <string.h>
#include <math.h>
#include "vesalint.h"
#include "affine.c"
typedef struct RT_camera
{
float xpos,ypos,zpos,d;
}RT_CAMERA;
typedef struct RT_esfera
{
float xpos,ypos,zpos,radi;
float coeff; //coeficientes
VECTOR ambient,diffuse,specular;
float brillo;
}RT_ESFERA;
typedef struct RT_luz
{
float xpos,ypos,zpos;
VECTOR color;
}RT_LUZ;
typedef struct RT_escena
{
int num_luz,num_esfera,num_camera;
RT_ESFERA *esferas;
RT_LUZ *luces;
RT_CAMERA *cameras;
VECTOR ambient;
}RT_ESCENA;
#pragma aux Set_Mode=\
"int 10h"\
modify [ax]\
parm [ax]
void RT_render(RT_ESCENA *esc, unsigned char *dest) //primary render
{
int xc,yc,sc,lc,min_esfera,ppos;
float bpart,disc,t1,t2,min_t,cos_angulo,brillo;
VECTOR ray,posicion,normal,v_luz,color;
ppos=0;
for (sc=0;sc<esc->num_esfera;sc++)
esc->esferas[sc].coeff=pow(esc->cameras->xpos-esc->esferas[sc].xpos,2)+
pow(esc->cameras->ypos-esc->esferas[sc].ypos,2)+
pow(esc->cameras->zpos-esc->esferas[sc].zpos,2)-
pow(esc->esferas[sc].radi,2);
for (yc=-100;yc<100;yc+=1)
for (xc=-160;xc<160;xc+=1)
{
min_t=1000000.0;
min_esfera=-1;
ray.v1=xc;
ray.v2=yc;
ray.v3=esc->cameras->d;
ray=unit_vtr(ray);
for (sc=0;sc<esc->num_esfera;sc++)
{
bpart=(esc->cameras->xpos-esc->esferas[sc].xpos)*ray.v1+
(esc->cameras->ypos-esc->esferas[sc].ypos)*ray.v2+
(esc->cameras->zpos-esc->esferas[sc].zpos)*ray.v3;
disc=pow(bpart,2)-esc->esferas[sc].coeff;
if (disc>0)
{
disc=sqrt(disc);
t1=-bpart+disc;
t2=-bpart-disc;
if ((t1>0)&&(t1<min_t))
{
min_t=t1;
min_esfera=sc;
}
if ((t2>0)&&(t2<min_t))
{
min_t=t2;
min_esfera=sc;
}
}
}
if (min_esfera>=0)
{
posicion.v1=ray.v1*min_t;
posicion.v2=ray.v2*min_t;
posicion.v3=ray.v3*min_t;
normal.v1=(posicion.v1-esc->esferas[min_esfera].xpos)/esc->esferas[min_esfera].radi;
normal.v2=(posicion.v2-esc->esferas[min_esfera].ypos)/esc->esferas[min_esfera].radi;
normal.v3=(posicion.v3-esc->esferas[min_esfera].zpos)/esc->esferas[min_esfera].radi;
color.v1=esc->esferas[min_esfera].ambient.v1*esc->ambient.v1;
color.v2=esc->esferas[min_esfera].ambient.v2*esc->ambient.v2;
color.v3=esc->esferas[min_esfera].ambient.v3*esc->ambient.v3;
brillo=esc->esferas[min_esfera].brillo;
for (lc=0;lc<esc->num_luz;lc++)
{
v_luz.v1=esc->luces[lc].xpos;
v_luz.v2=esc->luces[lc].ypos;
v_luz.v3=esc->luces[lc].zpos;
v_luz=vtr_sub_vtr(v_luz,posicion);
v_luz=unit_vtr(v_luz);
cos_angulo=vtr_dot_mul_vtr(v_luz,normal);
if (cos_angulo>0)
{
color.v1+=cos_angulo*esc->esferas[min_esfera].diffuse.v1*esc->luces[lc].color.v1;
color.v2+=cos_angulo*esc->esferas[min_esfera].diffuse.v2*esc->luces[lc].color.v2;
color.v2+=cos_angulo*esc->esferas[min_esfera].diffuse.v3*esc->luces[lc].color.v3;
}
}
dest[ppos ]=max(min(color.v3,254),0);
dest[ppos+1]=max(min(color.v2,254),0);
dest[ppos+2]=max(min(color.v1,254),0);
}
else
{
dest[ppos ]=0;
dest[ppos+1]=0;
dest[ppos+2]=0;
}
ppos+=3;
}
}
RT_ESCENA *ray_testing;
unsigned char *Virtpant1;
void main(int argc, char *argv[])
{
float movi=0;
ray_testing=malloc(sizeof(RT_ESCENA));
ray_testing->num_esfera =1;
ray_testing->num_camera =1;
ray_testing->num_luz =1;
ray_testing->esferas=malloc(sizeof (RT_ESFERA)*ray_testing->num_esfera);
ray_testing->cameras=malloc(sizeof (RT_CAMERA)*ray_testing->num_camera);
ray_testing->luces =malloc(sizeof (RT_LUZ )*ray_testing->num_luz);
ray_testing->ambient.v1=128;
ray_testing->ambient.v2=128;
ray_testing->ambient.v3=128;
ray_testing->esferas[0].xpos=0;
ray_testing->esferas[0].ypos=0;
ray_testing->esferas[0].zpos=900;
ray_testing->esferas[0].radi=150;
ray_testing->esferas[0].ambient.v1=0.5;
ray_testing->esferas[0].ambient.v2=0;
ray_testing->esferas[0].ambient.v3=0;
ray_testing->esferas[0].diffuse.v1=0.5;
ray_testing->esferas[0].diffuse.v2=0.25;
ray_testing->esferas[0].diffuse.v3=0;
ray_testing->esferas[0].specular.v1=0.0;
ray_testing->esferas[0].specular.v2=0.0;
ray_testing->esferas[0].specular.v3=0.0;
ray_testing->esferas[0].brillo=5;
ray_testing->luces[0].xpos=-100;
ray_testing->luces[0].ypos=-100;
ray_testing->luces[0].zpos=600;
ray_testing->luces[0].color.v1=255;
ray_testing->luces[0].color.v2=255;
ray_testing->luces[0].color.v3=255;
ray_testing->cameras[0].xpos=0;
ray_testing->cameras[0].ypos=0;
ray_testing->cameras[0].zpos=0;
ray_testing->cameras[0].d=256;
Virtpant1=malloc(320*200*3);
Active.Screen.Width=320;
Active.Screen.Height=200;
Active.Screen.bpp=32;
Active.Work.Width=320;
Active.Work.Height=200;
Active.Work.bpp=24;
Active.EnableLFB=1;
if (!InitSetMode())
{
Active.Screen.bpp=24;
if (!InitSetMode())
{
Active.Screen.bpp=16;
if (!InitSetMode())
{
Active.Screen.bpp=15;
if (!InitSetMode())
{
Active.Screen.bpp=-1;
Active.Screen.Height*=2;
InitSetMode();
}
}
}
}
while (!kbhit())
{
ray_testing->luces[0].xpos=500*sin(movi/10);
ray_testing->luces[0].zpos=1000-500*cos(movi/10);
movi++;
RT_render(ray_testing,Virtpant1);
Flip(Virtpant1);
}
getch();
Free_Memory();
Set_Mode(0x3);
}